package wickethub.data;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.TopDocs;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.IModel;

import wickethub.domain.Component;
import wickethub.domain.Resource;
import wickethub.repository.ResourceRepository;
import wickethub.web.app.EntityDetachableModel;

import com.google.inject.Provider;

/**
 * 
 * @author ftreacy
 */
public class SearchResultProvider implements IDataProvider<Resource> {

	private final TopDocs docs;
	private final Provider<IndexSearcher> searcherProvider;
	private final ResourceRepository repo;
	
	public SearchResultProvider(String query, Provider<IndexSearcher> searcherProvider, ResourceRepository repo) {
		
		this.searcherProvider = searcherProvider;
		this.repo = repo;
		
		try {
			QueryParser qp = new QueryParser("text", new SimpleAnalyzer());
			Query q = qp.parse(query);
			TopDocCollector collector = new TopDocCollector(10);
			searcherProvider.get().search(q, collector);
			docs = collector.topDocs();
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
	}
	
	public Iterator<Resource> iterator(int first, int count) {
		
		ScoreDoc[] hits = docs.scoreDocs;
		
		List<Resource> list = new ArrayList<Resource>(10);
		
		try {

			for (int i = 0; i < hits.length; i++) {
				int docId = hits[i].doc;
				Document d = searcherProvider.get().doc(docId);
				Resource resource = new Component(); // any Resource impl will do
				resource.setId(new Long(d.get("id")));
				list.add(resource);
			}
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
		return list.iterator();
		
	}
	
	public int size() {
		return docs.totalHits;
	}

	public IModel<Resource> model(Resource resource) {
		return new EntityDetachableModel<Resource>(resource.getClass(), resource.getId(), repo);
	}

	public void detach() {
		// no detaching required
	}

}
